Skip to main content

Integration testing

When it comes to implement integration tests, there is a lot of debate. Aren't unit tests enough? What are you trying to cover with them?

  • in the Tests folder, add a new xUnit project named SpeakerService.Tests.Integration

We will add a helper class that extends WebApplicationFactory<TProgram>. This will allow us to configure a database used for tests(if- and we should use a different test database), and also allow us to create additional methods in-charge of channel creation.

Creating a custom Factory
public class MyFactory<TProgram> : WebApplicationFactory<TProgram> where
TProgram : class
{

}
  • Configure the WebHost
Configure the WebHost
 protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Test");
//builder.UseTestServer();
builder.ConfigureTestServices(services =>
{
//in here we configure what we need
});
builder.UseTestServer();
}

  • Create an additional method that will return a gRPC client
CreateGrpcClient method
public SpeakerServiceDefinition.SpeakerServiceDefinitionClient CreateGrpcClient()
{
var httpClient = CreateClient();

var channel = GrpcChannel.ForAddress(httpClient.BaseAddress!, new GrpcChannelOptions
{
HttpClient = httpClient,
});

return new SpeakerServiceDefinition.SpeakerServiceDefinitionClient(channel);
}

Writing the test class

  • add a class named SpeakerServiceTests that extends our MyFactory class
Title
public class SpeakerServiceTests : IClassFixture<MyFactory<Program>>
{

}
  • prepare the constructor, passing the right
private readonly MyFactory<Program> factory;

public SpeakerServiceTests(MyFactory<Program> factory)
{
this.factory = factory;
}

  • write the test method applying the AAA pattern
The test objects

We should work on a test database, that is seeded with some test data, or create some objects, insert them in the db, and then make assertions using them

  • Arrange - call the factory to obtain a gRPC client, build an object that you know will be the response object
            // Arrange
var client = factory.CreateGrpcClient();
var expectedResponse = new SpeakerResponse()
{
Id = 5,
City = "Oslo",
Country = "Norway",
Email = "",
Bio = "",
FirstName = "",
LastName = "",
Website = ""
};

  • Act
Act
 var response = await client.GetByIdAsync(new SpeakerFilterRequest { Id = 5 });

  • Assert
Act
response.Should().BeEquivalentTo(expectedResponse);
DON't open
Full implementation

public class SpeakerServiceTests : IClassFixture<MyFactory<Program>>
{
private readonly MyFactory<Program> factory;

public SpeakerServiceTests(MyFactory<Program> factory)
{
this.factory = factory;
}

[Fact]
public async Task GetById_Async()
{
// Arrange
var client = factory.CreateGrpcClient();
var expectedResponse = new SpeakerResponse()
{
Id = 5,
City = "Oslo",
Country = "Norway",
Email = "",
Bio = "",
FirstName = "",
LastName = "",
Website = ""
};

var response = await client.GetByIdAsync(new SpeakerFilterRequest { Id = 5 });



// Assert
response.Should().BeEquivalentTo(expectedResponse);
}


}